import { createAsyncThunk, createSlice, isRejected } from "@reduxjs/toolkit";
import { getRequest, postRequest } from "../util/Net";
import { RootState, store } from "./store";


interface TextEntry {
  id: number;
  text: string;
  result: boolean;
  analyzeTime: string;
}

interface ModelEntry {
  id: number;
  name: string;
  type: string;
}

interface FetchHistoryRequest {
  filter: string;
}

interface AnalyzeParams {
  data: string[];
  filter: string;
}

interface DeleteHistoryParams {
  id: number;
  filter: string;
}

interface DeleteHistoryRequest {
  id: number;
}

interface AnalyzeResult {
  text: string;
  result: boolean;
  id: number;
}

interface AnalyzeState {
  entries: TextEntry[];
  models: ModelEntry[];
  result: AnalyzeResult[];
  resultLoaded: boolean;
}

const initialState: AnalyzeState = {
  entries: [],
  models: [{
    id: 1,
    name: 'VAE 模型',
    type: 'PyTorch'
  }],
  result: [],
  resultLoaded: false
};

const analyze = createAsyncThunk('api/analyze', async (params: AnalyzeParams) => {
  const response = await postRequest<boolean[], string[]>({
    url: '/recognition/analyzeStrings',
    request: params.data
  });
  store.dispatch(fetchHistory(params.filter));
  return response.data;
});

const fetchHistory = createAsyncThunk('api/fetchHistory', async (filter: string) => {
  const response = await getRequest<TextEntry[], FetchHistoryRequest>({
    url: '/recognition/getHistory',
    params: {
      filter: filter
    }
  });
  return response.data;
});

const deleteHistory = createAsyncThunk('api/deleteHistory', async (params: DeleteHistoryParams) => {
  const response = await postRequest<null, DeleteHistoryRequest>({
    url: '/recognition/deleteHistory',
    request: {
      id: params.id
    }
  });
  store.dispatch(fetchHistory(params.filter));
  return response.data;
});

const analyzeSlice = createSlice({
  name: 'analyze',
  initialState: initialState,
  reducers: {
    clearResult: (state) => {
      state.result = [];
      state.resultLoaded = false;
    },
    clear: (state) => {
      state.entries = [];
      state.result = [];
      state.resultLoaded = false;
    }
  },
  extraReducers: (builder) => {
    builder.addCase(analyze.fulfilled, (state, action) => {
      const length: number = action.payload.result.length;
      const result: AnalyzeResult[] = []
      for (let i = 0; i < length; ++i){
        result.push({
          text: action.meta.arg.data[i],
          result: action.payload.result[i],
          id: i
        });
      }
      state.result = result;
      state.resultLoaded = true;
    }).addCase(fetchHistory.fulfilled, (state, action) => {
      state.entries = action.payload.result;
    }).addCase(deleteHistory.fulfilled, (state, action) => {

    }).addMatcher(isRejected, (state, action) => {

    });
  }
});

export default analyzeSlice.reducer;
export type { ModelEntry, TextEntry, AnalyzeResult };
export const analyzeActions = { ...analyzeSlice.actions, analyze, fetchHistory, deleteHistory };
export const selectAnalyzeModels = (root: RootState) => root.analyzeReducer.models;
export const selectAnalyzeResult = (root: RootState) => root.analyzeReducer.result;
export const selectAnalyzeResultLoaded = (root: RootState) => root.analyzeReducer.resultLoaded;
export const selectHistoryEntries = (root: RootState) => root.analyzeReducer.entries;